package com.ives.launcher.view;

import java.util.ArrayList;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.ives.launcher.logic.DragContainer;
import com.ives.launcher.logic.DragController;
import com.ives.launcher.logic.DragController.DragLifeListener;
import com.ives.launcher.model.ItemInfo;
import com.ives.launcher.model.ItemInfo_App;
import com.ives.launcher.model.ItemInfo_Floder;
import com.ives.launcher.util.ILog;
import com.ives.launcher.util.ImageTool;
/**
 * 桌面上的顶层View，用于装View_Page_Root和“抽屉”
 * 实现DragController，用来发起拖动图标的事件
 * 首先判断是普通触摸还是长按事件，再根据不同的情况做出不同处理。
 * 处理cell拖动事件
 * 此层必须拦截长按事件,以支持拖动操作
 * @author ives
 * 
 */
public class View_Root extends RelativeLayout implements DragController,DragContainer,DragLifeListener{
	/**此状态非常重要，很多类都需要维护和使用此状态**/
	public static int TOUCH_TYPE;//手指触摸屏幕的状态类型
	public static final int TOUCH_TYPE_NORMAL = 0;//默认状态，表示手指触摸到屏幕，这种状态可能发展成所有的情况
	public static final int TOUCH_TYPE_CLICK = 1;//普通点击事件
	public static final int TOUCH_TYPE_SCROLL_SCREEN = 2;//滑动屏幕
	public static final int TOUCH_TYPE_DRAG_CELL = 3;//拖动某个cell
	public static final int TOUCH_TYPE_DRAG_COPY = 4;//拖动某个cell(复制)
	public static final int TOUCH_TYPE_LONGPRESS = 5;//长按桌面，但是没有点击图标
	//表示屏幕是否被长按，因为此类无法直接处理长按事件，所以需要其他类辅助，改变此状态的通常为最末端的容器eg:View_Page_Item
	public static boolean isLongPress;
	public static boolean isDragging;//是否在拖动过程中
	
	private View_SlidingDrawer view_Slidingdrawer;// 抽屉
	
	/**拖动支持**/
	public View_Drag view_Dragging;//正在被拖动的view
	View_Page_Root page_root;
	/**
	 * 最后一次拖动cell之前的位置
	 */
	public int [] lastPoint = new int[2];
	
	private Activity activity;
	
	//拖动监听事件队列
	private ArrayList<DragLifeListener> draggingListeners = new ArrayList<DragController.DragLifeListener>();
	public View_Root(Context context) {
		this(context,null);
	}

	public View_Root(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		addListener();
		this.setBackgroundColor(Color.BLACK);
	}

	public View_Root(Context context, AttributeSet attrs) {
		this(context, attrs,0);
	}
	/**
	 * 通过一个cell来生成一个可拖动的View_Drag对象
	 * @param cell 通过此cell来生成可拖动的View_Drag对象
	 * @param viewGroup cell的容器
	 * @return
	 */
	public View_Drag makeDragViewFromCell(View_Cell cell,DragContainer group){
		int [] xy = new int[]{0,0};
		cell.getLocationOnScreen(xy);
		Rect rect = new Rect();
		getWindowVisibleDisplayFrame(rect);
		
		View_Root.LayoutParams params2 = new LayoutParams(xy[0],xy[1]-rect.top,cell.getWidth(),cell.getWidth());
		View_Drag drag = new View_Drag(activity);
		drag.setmPrams(params2);
		drag.setLayoutParams(params2);
		
		
		drag.setStartCell(cell);
		drag.startGroup = group;
		drag.setBackgroundDrawable(new BitmapDrawable(cell.getIcon()));
		return drag;
	}
	@Override
	public void startDrag(View v, DragContainer source,int dragType) {
		isDragging= true;
		//添加正在被拖动的view
		this.addView(view_Dragging);
		if(dragType==TOUCH_TYPE_DRAG_CELL){
			//将拖动cell设置成不可见
			v.setVisibility(GONE);
			//将被拖动的cell占据的位置设置成未使用
			View_Page_Item.LayoutParams lp = (View_Page_Item.LayoutParams) v.getLayoutParams();
			source.setPositionStatus(lp.startCellsX,lp.startCellsY,lp.cellWidth,lp.cellHeight,false);
			//更新lastpoint
			View_Page_Item.LayoutParams pms = (View_Page_Item.LayoutParams) v.getLayoutParams();
			lastPoint[0] =pms.startCellsX;
			lastPoint[1] = pms.startCellsY;
		}else if(dragType==TOUCH_TYPE_DRAG_COPY){
			//将view_allAppsGrid设置成不可见
			
		}
		
		//通知对应监听器
		drag_Start(view_Dragging,dragType);
		
	}
	
	@Override
	public void addView(View child) {
		super.addView(child);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		if(view_Dragging!=null){
			View_Root.LayoutParams p = (LayoutParams) view_Dragging.getmPrams();
			view_Dragging.layout(p.x,p.y,p.x+p.width,p.y+p.height);
			return;
		}
	}
	/**
	 * 专门用于移动中的cell的布局
	 * @author ives
	 * 
	 */
	public static class LayoutParams extends ViewGroup.MarginLayoutParams {
		public int x;
		public int y;
		public LayoutParams(Context c, AttributeSet attrs) {
			super(c, attrs);
		}
		
		public LayoutParams(ViewGroup.LayoutParams source) {
			super(source);
		}
		public LayoutParams(int x,int y,int w,int h) {
			super(w,h);
			this.x  = x;
			this.y = y;
			this.width = w;
			this.height = h;
		}

	}
	/**
	 * 决定是否拦截事件，只有在cell正在拖动的时候才进行拦截
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		if(ev.getAction()==MotionEvent.ACTION_DOWN){
			//清除被点击对cell状态
			if(View_Cell.clickingView!=null){
				View_Cell.clickingView.setClicking(false);
				View_Cell.clickingView.postInvalidate();
				View_Cell.clickingView = null;
			}
		}
			
		return isLongPress;
	}
	@Override
	public boolean onTouchEvent(MotionEvent event){
		int action = event.getAction();//动作类型
		/*解除各种状态*/
		if(action==MotionEvent.ACTION_UP){//解除长按事件
			if(TOUCH_TYPE==TOUCH_TYPE_DRAG_CELL){//如果先前是长按状态，就更新当前桌面
				//寻找合适存放cell的位置
				disposeDragOver((int)event.getX(),(int)event.getY(),view_Dragging);
			}
			isLongPress = false;
			isDragging= false;
			TOUCH_TYPE = TOUCH_TYPE_NORMAL;
			//清除被点击对cell状态
			if(View_Cell.clickingView!=null){
				View_Cell.clickingView.setClicking(false);
				View_Cell.clickingView.postInvalidate();
			}
			return true;
		}
		/*处理长按事件*/
		if(isLongPress){
			if(TOUCH_TYPE==TOUCH_TYPE_DRAG_CELL){//处理拖动过程
				if(action==MotionEvent.ACTION_MOVE){//持续移动
					return disposeDrop(event, view_Dragging);
				}
			}else if(TOUCH_TYPE==TOUCH_TYPE_NORMAL) {//进入了长按阶段，但是还没触发拖动事件
				if(view_Dragging==null){//长按桌面，但是没有点击图标
					ILog.w("","长按桌面，但是没有点击图标");
					getContext().startActivity(new Intent(Intent.ACTION_SET_WALLPAPER));
					TOUCH_TYPE = TOUCH_TYPE_LONGPRESS;
					this.postInvalidate();
				}else{//如果长按在某个cell上面，则发起一次拖动事件
					TOUCH_TYPE = TOUCH_TYPE_DRAG_CELL;
					startDrag(view_Dragging.getStartCell(), view_Dragging.getDraggingContainer(),TOUCH_TYPE_DRAG_CELL);
				}
			}
		}else{
			
		}
		return super.onTouchEvent(event);
	}
	long lastTimeExecute_getDraggingContainerByPoint = 0;//最后一次执行getDraggingContainerByPoint的时间
	DragContainer lastExecute_result = null;//存储上一次执行getDraggingContainerByPoint的执行结果
	final static long intervalExecute_getDraggingContainerByPoint = 200;//执行getDraggingContainerByPoint的间隔时间
	/**
	 * 根据一个点寻找所处的容器
	 * @param f 中心点x
	 * @param g 中心点y
	 * @return
	 */
	public  DragContainer getDraggingContainerByPoint(int x,int y){
		if(System.currentTimeMillis()-lastTimeExecute_getDraggingContainerByPoint<intervalExecute_getDraggingContainerByPoint){
			return lastExecute_result;
		}
		lastTimeExecute_getDraggingContainerByPoint = System.currentTimeMillis();
		int count = this.getChildCount();
		Rect rect=new Rect();
		for (int i = 0; i < count; i++) {
			View v =  getChildAt(i);
			v.getHitRect(rect);
			if(rect.contains(x, y))
				if(v instanceof DragContainer){
					lastExecute_result = (DragContainer) v;
					return lastExecute_result;
				}else{
					return lastExecute_result=null;
				}
			
		}
		return lastExecute_result=null;
	}
	/**
	 * 寻找正在处理拖动的容器，如果没有拖动，则返回null
	 * @return
	 */
	public DragContainer getDraggingContainer(){
		if(isDragging==false)return null;
		if(view_Dragging==null)return null;
		return view_Dragging.getDraggingContainer();
	}

	
	private void addListener(){
		this.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
			}
		});
		this.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				return false;
			}
		});
	}
	/**
	 * 关闭抽屉
	 */
	public void closeSlidingDrawer(){
		view_Slidingdrawer.close();
	}
	/**
	 * 处理当拖动结束的时候
	 * @param touchX
	 * @param touchY
	 * @param drag
	 */
	private void disposeDragOver(int touchX,int touchY,View_Drag drag){
		//判断推拽操作是否跨了页面,如果跨了页面，则需要先移除cell原来所在的容器
		findDropCellFinalPosition(touchX, touchY, drag);
		//善后工作
		this.removeView(view_Dragging);
		if(view_Dragging!=null)view_Dragging.getStartCell().setVisibility(VISIBLE);
		view_Dragging = null;
		//通知各个容器
		for (int i = 0; i < getChildCount(); i++) {
			getChildAt(i).postInvalidate();
		}
		if(getPage_root().scaleRatioX!=10){
			getPage_root().setShowModel(1);
		}
	}
	/**
	 * 为移动的cell寻找合适的存放位置
	 * @param touchX
	 * @param touchY
	 * @param cell
	 * @return
	 */
	@Override
	public int[] findDropCellFinalPosition(int touchX, int touchY,View_Drag drag) {
		//首先确定当前触摸位置所在的DragContainer
		DragContainer group = getDraggingContainerByPoint(view_Dragging.getLeft()+view_Dragging.getWidth()/2,view_Dragging.getTop()+view_Dragging.getHeight()/2);
		int [] position = null;//最终位置
		//调用容器处理拖动的方法进行自行处理
		if(group==null)return null;
		position = group.findDropCellFinalPosition(touchX, touchY, drag);
		//首先判断是否可以移动到该位置
		boolean isMove = group.checkCanMoveToPosition(position[0], position[1], drag);
		//如果可以直接移动，就直接移动，否则判断导致不可移动的是文件夹还是普通cell
		if(isMove){
			//调用DragContainer的findDropCellFinalPosition方法来查找应该存放的位置
			 group.moveToPosition(position[0], position[1],drag);	
		}else{
			//找到导致失败的cell
			View view = group.getChildByPosition(position[0], position[1]);
			if(view!=null){
				if(view instanceof View_Cell){
					View_Cell cell = (View_Cell) view;
					if(cell.getItemInfo().itemType==ItemInfo.Type_Floder){//如果此view是一个文件夹，则将cell移动进文件夹
						if(drag.getStartCell().getItemInfo().itemType==ItemInfo.Type_Floder){
							//提醒是否合并文件夹
							((ItemInfo_Floder)cell.getItemInfo()).items.addAll(((ItemInfo_Floder)drag.getStartCell().getItemInfo()).items);
							cell.getItemInfo().icon = ImageTool.makeFloderIcon(((ItemInfo_Floder)cell.getItemInfo()), getContext());
							cell.setIcon(cell.getItemInfo().icon);
							cell.postInvalidate();
						}else{
							view_Dragging.startGroup.removeCell(view_Dragging.getStartCell());
							((ItemInfo_Floder)cell.getItemInfo()).addItem(view_Dragging.getStartCell().getItemInfo());
							cell.getItemInfo().icon = ImageTool.makeFloderIcon(((ItemInfo_Floder)cell.getItemInfo()), getContext());
							cell.setIcon(cell.getItemInfo().icon);
							cell.postInvalidate();
						}
						
					}else {//如果view是一个普通的cell，则创建一个默认的文件夹，并且将两个cell都装进此文件夹
						//添加一个文件夹
						ItemInfo_Floder floder = new ItemInfo_Floder();
						floder.items.add(cell.getItemInfo());
						floder.items.add(drag.getStartCell().getItemInfo());
						
						floder.title = "未命名文件夹";
						floder.itemType = ItemInfo.Type_Floder;
						cell.setItemInfo(floder);
						//给floder添加点击事件
						cell.setmOnClickLinstener(floder.makeOnClickLinstener(getContext(),cell));
						cell.getItemInfo().icon = ImageTool.makeFloderIcon(((ItemInfo_Floder)cell.getItemInfo()), getContext());
						cell.setIcon(cell.getItemInfo().icon);
						cell.setTitle(floder.title.toString());
						cell.postInvalidate();
						
					}
					//将cell从它原本的容器移除
					drag.startGroup.removeCell(drag.getStartCell());
					//将原本的位置
				}
			}
			
			//更新容器位置占据信息
		}
	//检查失败的
	return position;
	}
	@Override
	public void onDragIn(View view, DragContainer source) {
		
	}

	@Override
	public void onDropOut(View view, DragContainer target) {
		
	}

	@Override
	public void onDropCompleted(View target, boolean success) {
		
	}

	@Override
	public boolean disposeDrop(MotionEvent event, View_Drag drag) {
		//取得正处在的容器
		DragContainer group = getDraggingContainerByPoint(view_Dragging.getLeft()+view_Dragging.getWidth()/2,view_Dragging.getTop()+view_Dragging.getHeight()/2);
		//让此view随着手指的移动而移动，首先确定移动的位置
		int left = (int) event.getX()-view_Dragging.getStartCell().getStartPoint()[0];
		int top = (int) event.getY()-view_Dragging.getStartCell().getStartPoint()[1];
		view_Dragging.layout(left,top,left+view_Dragging.getMeasuredWidth(),top+view_Dragging.getMeasuredHeight());
		view_Dragging.bringToFront();
		//调用容器处理拖动的方法进行自行处理
		if(group!=null){
			group.disposeDrop(event, drag);
			//判断是否跨页,如果是，则调用对应监听器
			if(group!=drag.getDraggingContainer()){
				drag.startGroup.onDropOut(drag, group);
				group.onDragIn(drag, drag.startGroup);
			}
		}
		//告诉所有注册了“拖动生命周期监听器”的监听器现在的拖动状态
		drag_Dragging(view_Dragging);
		return true;
	}
	/**********/
	@Override
	public void drag_Start(View_Drag drag,int dragType) {
		int count = draggingListeners.size();
		for (int i = 0; i < count; i++)
			draggingListeners.get(i).drag_Start(view_Dragging,dragType);
	}

	@Override
	public void drag_Over(View_Drag drag) {
		int count = draggingListeners.size();
		for (int i = 0; i < count; i++)
			draggingListeners.get(i).drag_Over(view_Dragging);
	}

	@Override
	public void drag_Dragging(View_Drag drag) {
		int count = draggingListeners.size();
		for (int i = 0; i < count; i++)
			draggingListeners.get(i).drag_Dragging(view_Dragging);
	}

	@Override
	public void drag_ContainerChange(View_Drag drag) {
		int count = draggingListeners.size();
		for (int i = 0; i < count; i++)
			draggingListeners.get(i).drag_ContainerChange(view_Dragging);
	}
	@Override
	public View getChildByPosition(int x,int y){
		return null;
	}
	
	/**
	 * 设置背景图片,读取系统的
	 * @param index
	 * @param count
	 */
	public void setWallpaper(int index,int count,int swidth,int sheight){
		// 获取壁纸管理器
		WallpaperManager wallpaperManager = WallpaperManager.getInstance(getContext());
		// 获取当前壁纸
		Drawable wallpaperDrawable = wallpaperManager.getDrawable();
		// 将Drawable,转成Bitmap
		Bitmap bm = ((BitmapDrawable) wallpaperDrawable).getBitmap();
		// 需要详细说明一下，mScreenCount、getCurrentWorkspaceScreen()、mScreenWidth、mScreenHeight分别
		//对应于Launcher中的桌面屏幕总数、当前屏幕下标、屏幕宽度、屏幕高度.等下拿Demo的哥们稍微要注意一下
		float step = 0;
		// 计算出屏幕的偏移量
		step = (bm.getWidth() - swidth)/ count;
		// 截取相应屏幕的Bitmap
		Bitmap pbm = Bitmap.createBitmap(bm, (int) (index * step), 0,swidth,sheight);
		// 设置 背景
		setBackgroundDrawable(new BitmapDrawable(pbm));
	}
	/**
	 * 设置背景图片,读取系统的
	 * @param index
	 * @param count
	 */
	public void setWallpaper(int index,int count){
		// 获取壁纸管理器
		WallpaperManager wallpaperManager = WallpaperManager.getInstance(getContext());
		// 获取当前壁纸
		Drawable wallpaperDrawable = wallpaperManager.getDrawable();
		// 将Drawable,转成Bitmap
		Bitmap bm = ((BitmapDrawable) wallpaperDrawable).getBitmap();
		// 需要详细说明一下，mScreenCount、getCurrentWorkspaceScreen()、mScreenWidth、mScreenHeight分别
		//对应于Launcher中的桌面屏幕总数、当前屏幕下标、屏幕宽度、屏幕高度.等下拿Demo的哥们稍微要注意一下
		float step = 0;
		// 计算出屏幕的偏移量
		step = (bm.getWidth() - getWidth())/ count;
		// 截取相应屏幕的Bitmap
		Bitmap pbm = Bitmap.createBitmap(bm, (int) (index * step), 0,getWidth(),getHeight());
		// 设置 背景
		setBackgroundDrawable(new BitmapDrawable(pbm));
	}
	/**
	 * 添加DragLifeListener监听器
	 * @param listener
	 */
	public void addDraggingListener(DragLifeListener listener){
		draggingListeners.add(listener);
	}
	/**getter and setter**/
	public View_SlidingDrawer getView_Slidingdrawer() {
		return view_Slidingdrawer;
	}

	public void setView_Slidingdrawer(View_SlidingDrawer view_Slidingdrawer) {
		this.view_Slidingdrawer = view_Slidingdrawer;
	}

	public Activity getActivity() {
		return activity;
	}

	public void setActivity(Activity activity) {
		this.activity = activity;
	}

	/**lastPoint的操作，为保证同步，故此操作**/
	public int getLastPointX(){
		return lastPoint[0];
	}

	@Override
	public boolean moveToPosition(int x1,int y1,View_Drag drag) {

		return false;
	}

	@Override
	public void setPositionStatus(int x, int y, int w, int h, boolean used) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void removeCell(View_Cell cell) {
		// TODO Auto-generated method stub
		
	}

	public View_Page_Root getPage_root() {
		return page_root;
	}

	public void setPage_root(View_Page_Root page_root) {
		this.page_root = page_root;
	}

	@Override
	public boolean checkCanMoveToPosition(int x, int y, View_Drag drag) {
		// TODO Auto-generated method stub
		return false;
	}
	
	/****/
	
}
